﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace CSharpXDL
{
    class HttpConnect : XDLConnect
    {

        long length;
        long range;
        internal NetworkStream stream;
        internal Uri uri;
        WebHeaderCollection requestHeader;
        WebHeaderCollection responseHeader;
        internal BinaryReader reader;
        Socket socket;
        internal int StateCode;
        String StatusDescription, ProtocolVersion;
        public int GetStateCode()
        {

            return StateCode;
        }
        public long ContentLength()
        {
            return length;
        }
        public HttpConnect(Socket socket,long range)
        {
            this.socket = socket;
            stream = new NetworkStream(socket,true);
            this.range = range;
        }
        internal void init(Uri uri)
        {
            this.uri = uri;
           StreamWriter writer = new StreamWriter(stream);
                    
           requestHeader = new WebHeaderCollection();
           responseHeader= new WebHeaderCollection();
           requestHeader.Add(HttpRequestHeader.Range, "bytes=" + range + "-");
            requestHeader.Add(HttpRequestHeader.Host, uri.Host);
           //requestHeader.Add(HttpRequestHeader.Accept, "*/*");
           //requestHeader.Add(HttpRequestHeader.Date, DateTime.Now.ToString());
           //requestHeader.Add(HttpRequestHeader.UserAgent, "Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)");
           
           byte[] hbs = requestHeader.ToByteArray();
           char[] c2 = System.Text.Encoding.ASCII.GetString(hbs, 0, hbs.Length).Replace(": ",":").ToCharArray();
           writer.WriteLine("GET " + uri.PathAndQuery + " HTTP/1.1");    
           writer.Write(c2);
           writer.Flush();
          // String ss = readHeader();
          // Console.WriteLine(ss);
           StreamReader reader2 = new StreamReader(readHeader());
           String l = "";
           try
           {
               for (int i = 0; l!=null;i++ )
               {
                   l = reader2.ReadLine();
                   if (l.Equals(""))
                   {
                       break;
                   }
                   if (i == 0) {
                       String[] l1=l.Split(' ');
                       ProtocolVersion = l1[0];
                      StateCode= int.Parse(l1[1]);
                      StatusDescription = l1[2];
                      Console.WriteLine(StateCode + " " + StatusDescription);
                      continue;
                   }
                   
                   String[] h= l.Split(':');
                   responseHeader.Add(h[0],h[1]);
                   if (String.Equals("Content-Length", h[0], StringComparison.CurrentCultureIgnoreCase))
                       this.length=long.Parse(h[1]);
               }
               
              //int ttt = stream.ReadByte();
               Console.WriteLine( DateTime.Now.ToLocalTime() + " " + stream.DataAvailable);
               reader = new BinaryReader(stream);
               //int ooo=reader.ReadByte();
           } catch (Exception ee) {
               Console.WriteLine(ee.StackTrace);
           }
     
           

        }
        MemoryStream readHeader()
        {
            MemoryStream memStream = new MemoryStream();

            byte b0=(byte)stream.ReadByte();
           // List<byte> bs = new List<byte>();
          //  bs.Add(b0);
            memStream.WriteByte(b0);
            while(true){
                if(b0==0x0d){
                    byte b1 = (byte)stream.ReadByte();
                    memStream.WriteByte(b1);
                    if (b1 == 0x0a) {
                        byte b2 = (byte)stream.ReadByte();
                        memStream.WriteByte(b2);
                        if (b2 == 0x0d)
                        {
                            byte b3 = (byte)stream.ReadByte();
                            memStream.WriteByte(b3);
                            if (b3 == 0x0a) {
                                break;
                            }
                        }
                    }
                }
                b0 = (byte)stream.ReadByte();
                memStream.WriteByte(b0);
            }
            memStream.Seek( 0,SeekOrigin.Begin);
           // Console.WriteLine("bs.ToArray().Length:" + bs.ToArray().Length);
            return memStream;// System.Text.Encoding.ASCII.GetString(bs.ToArray());
        }
        public HttpConnect(WebHeaderCollection requestHeader)
        {
            this.requestHeader = requestHeader;
        }
        public BinaryReader GetResponseStream()
        {
            return reader;
            
        }

        public void t() { 
            while(true){
                byte[] bs=reader.ReadBytes(10);
               sbyte sb= Convert.ToSByte(bs[0]);
              //  int b = reader.ReadByte();
                Console.WriteLine(sb);
            }
        }
        public WebHeaderCollection ResponseHeader() {
            return responseHeader;
        }
        public WebHeaderCollection RequestHeader()
        {
            return requestHeader;
        }
        public String GetStatusDescription()
        {
            return StatusDescription;
        }

        public void Close() {
            this.reader.Close();
            this.stream.Close();
            this.socket.Close();
        }
 
    }
}
